// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// I [author] rhyme_lph
// q [email]  rhymelph@gmail.com
// Y [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/entities/role_permission_entity.dart';
import 'package:finance_app/src/http_service/http_cpf_contribution_service.dart';
import 'package:finance_app/src/http_service/http_permission_service.dart';
import 'package:finance_app/src/mixin/init_edit_data_mixin.dart';
import 'package:finance_app/src/utils/permission_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:flutter/material.dart';

class NewRoleProvider extends BaseProvider<List<PermissionEntity>>
    with InitEditDataMixin<List<PermissionEntity>> {
  TextEditingController nameController = TextEditingController();

  RolePermissionEntity rolePermission;

  bool homeDashboard = false;
  bool quotation = false;
  bool invoice = false;
  bool purchaseOrder = false;
  bool bill = false;
  bool expense = false;
  bool creditDebitNote = false;
  bool productService = false;
  bool businessContact = false;
  bool cashBank = false;
  bool hrPayroll = false;
  bool salesReport = false;
  bool purchaseReports = false;
  bool inventoryReports = false;
  bool taxesReports = false;
  bool hrPayrollReports = false;
  bool accountantReports = false;
  bool chartOfAccounts = false;
  bool companySettings = false;
  bool inviteTeamMembers = false;

  bool isBack = false;

  @override
  Future get dataFuture =>
      rolePermission == null ? HttpPermissionService.newRole() : null;

  List<String> menuList = [
    'Edit Permission',
    'Duplicate Role',
    'Delete Role',
  ];

  void onSelectMenu(String value) {
    switch (value) {
      case 'Edit Permission':
        onChangeEditMode();
        break;
      case 'Duplicate Role':
        onDuplicateRole();
        break;
      case 'Delete Role':
        onDelete();
        break;
    }
  }

  void onDelete() {
    obtainContext?.call((context) async {
      bool isSuccess = false;
      await post(HttpPermissionService.deleteRole(rolePermission.id),
          loadingTip: S.current.loading,
          autoHandler: AutoHandler.Toast, onSuccess: (result) {
        isSuccess = true;
      });
      if (isSuccess == true) {
        await showDeleteRoleSuccessTipBottomSheet(context);
        Navigator.of(context).pop({
          'delete': true,
        });
      }
    });
  }

  void onDuplicateRole() {
    nameController.text = '';
    isEdit = false;
    rolePermission.id = null;
    update();
  }

  @override
  void initState() {
    super.initState();
    init(rolePermission?.id);
    if (rolePermission?.canEdit == 0) {
      menuList.remove('Edit Permission');
      menuList.remove('Delete Role');
    }
  }

  initPermission(RolePermissionEntity role, bool isDuplicate, bool isGoBack) {
    isBack = isGoBack ?? false;
    if (role == null) return;
    rolePermission = RolePermissionEntity().fromJson(role.toJson());
    nameController.text = role.name;
    homeDashboard = getPermissionCheck(PermissionUtils.homeDashboard);
    quotation = getPermissionCheck(PermissionUtils.quotation);
    invoice = getPermissionCheck(PermissionUtils.invoice);
    purchaseOrder = getPermissionCheck(PermissionUtils.purchaseOrder);
    bill = getPermissionCheck(PermissionUtils.bill);
    expense = getPermissionCheck(PermissionUtils.expense);
    creditDebitNote = getPermissionCheck(PermissionUtils.creditDebitNote);
    productService = getPermissionCheck(PermissionUtils.productService);
    businessContact = getPermissionCheck(PermissionUtils.businessContact);
    cashBank = getPermissionCheck(PermissionUtils.cashBank);
    hrPayroll = getPermissionCheck(PermissionUtils.hrPayroll);
    salesReport = getPermissionCheck(PermissionUtils.salesReport);
    purchaseReports = getPermissionCheck(PermissionUtils.purchaseReports);
    inventoryReports = getPermissionCheck(PermissionUtils.inventoryReports);
    taxesReports = getPermissionCheck(PermissionUtils.taxesReports);
    hrPayrollReports = getPermissionCheck(PermissionUtils.hrPayrollReports);
    accountantReports = getPermissionCheck(PermissionUtils.accountantReports);
    chartOfAccounts = getPermissionCheck(PermissionUtils.chartOfAccounts);
    companySettings = getPermissionCheck(PermissionUtils.companySettings);
    inviteTeamMembers = getPermissionCheck(PermissionUtils.inviteTeamMembers);

    if (isDuplicate) {
      nameController.text = '';
      isEdit = false;
      rolePermission.id = null;
    }
  }

  @override
  void dispose() {
    super.dispose();
  }

  String getPermissionName(String key) {
    return rolePermission.allPermissions
        .firstWhere((element) => element.key == key,
            orElse: () => PermissionEntity()..name = '')
        .name;
  }

  bool getPermissionCheck(String key) {
    return rolePermission.allPermissions
                .firstWhere((element) => element.key == key,
                    orElse: () => PermissionEntity())
                .checked ==
            1 ??
        false;
  }

  void onChangePermission(String permission) {
    switch (permission) {
      case PermissionUtils.homeDashboard:
        homeDashboard = !homeDashboard;
        break;
      case PermissionUtils.quotation:
        quotation = !quotation;
        break;
      case PermissionUtils.invoice:
        invoice = !invoice;
        break;
      case PermissionUtils.purchaseOrder:
        purchaseOrder = !purchaseOrder;
        break;
      case PermissionUtils.bill:
        bill = !bill;
        break;
      case PermissionUtils.expense:
        expense = !expense;
        break;
      case PermissionUtils.creditDebitNote:
        creditDebitNote = !creditDebitNote;
        break;
      case PermissionUtils.productService:
        productService = !productService;
        break;
      case PermissionUtils.businessContact:
        businessContact = !businessContact;
        break;
      case PermissionUtils.cashBank:
        cashBank = !cashBank;
        break;
      case PermissionUtils.hrPayroll:
        hrPayroll = !hrPayroll;
        break;
      case PermissionUtils.salesReport:
        salesReport = !salesReport;
        break;
      case PermissionUtils.purchaseReports:
        purchaseReports = !purchaseReports;
        break;
      case PermissionUtils.inventoryReports:
        inventoryReports = !inventoryReports;
        break;
      case PermissionUtils.taxesReports:
        taxesReports = !taxesReports;
        break;
      case PermissionUtils.hrPayrollReports:
        hrPayrollReports = !hrPayrollReports;
        break;
      case PermissionUtils.accountantReports:
        accountantReports = !accountantReports;
        break;
      case PermissionUtils.chartOfAccounts:
        chartOfAccounts = !chartOfAccounts;
        break;
      case PermissionUtils.companySettings:
        companySettings = !companySettings;
        break;
      case PermissionUtils.inviteTeamMembers:
        inviteTeamMembers = !inviteTeamMembers;
        break;
      default:
    }
    update();
  }

  List getUpdatedPermission() {
    List list = [];

    rolePermission.allPermissions.forEach((element) {
      switch (element.key) {
        case PermissionUtils.homeDashboard:
          if (homeDashboard) list.add({'id': element.id});
          break;
        case PermissionUtils.quotation:
          if (quotation) list.add({'id': element.id});
          break;
        case PermissionUtils.invoice:
          if (invoice) list.add({'id': element.id});
          break;
        case PermissionUtils.purchaseOrder:
          if (purchaseOrder) list.add({'id': element.id});
          break;
        case PermissionUtils.bill:
          if (bill) list.add({'id': element.id});
          break;
        case PermissionUtils.expense:
          if (expense) list.add({'id': element.id});
          break;
        case PermissionUtils.creditDebitNote:
          if (creditDebitNote) list.add({'id': element.id});
          break;
        case PermissionUtils.productService:
          if (productService) list.add({'id': element.id});
          break;
        case PermissionUtils.businessContact:
          if (businessContact) list.add({'id': element.id});
          break;
        case PermissionUtils.cashBank:
          if (cashBank) list.add({'id': element.id});
          break;
        case PermissionUtils.hrPayroll:
          if (hrPayroll) list.add({'id': element.id});
          break;
        case PermissionUtils.salesReport:
          if (salesReport) list.add({'id': element.id});
          break;
        case PermissionUtils.purchaseReports:
          if (purchaseReports) list.add({'id': element.id});
          break;
        case PermissionUtils.inventoryReports:
          if (inventoryReports) list.add({'id': element.id});
          break;
        case PermissionUtils.taxesReports:
          if (taxesReports) list.add({'id': element.id});
          break;
        case PermissionUtils.hrPayrollReports:
          if (hrPayrollReports) list.add({'id': element.id});
          break;
        case PermissionUtils.accountantReports:
          if (accountantReports) list.add({'id': element.id});
          break;
        case PermissionUtils.chartOfAccounts:
          if (chartOfAccounts) list.add({'id': element.id});
          break;
        case PermissionUtils.companySettings:
          if (companySettings) list.add({'id': element.id});
          break;
        case PermissionUtils.inviteTeamMembers:
          if (inviteTeamMembers) list.add({'id': element.id});

          break;
        default:
      }
    });
    return list;
  }

  void onSave() {
    FocusManager.instance.primaryFocus.unfocus();

    if (nameController.text == null || nameController.text == '') {
      showToast(S.current.please_enter_role_name);
      return;
    }

    obtainContext?.call((context) async {
      List permissionData = getUpdatedPermission();
      if (isEdit) {
        await post(
            HttpPermissionService.editRole(
              rolePermission.id,
              name: nameController.text,
              permissions: permissionData,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          await showEditRoleSuccessTipBottomSheet(context);
          isEdit = false;
          update();
        });
      } else {
        await post(
            HttpPermissionService.addNewRole(
              name: nameController.text,
              permissions: permissionData,
            ),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) async {
          await showCreateRoleSuccessTipBottomSheet(context);
          isEdit = false;
          RolePermissionEntity newRole =
              getEntityFromResult<RolePermissionEntity>(result);
          rolePermission.id = newRole.id;
          update();
        });
      }
    });
  }

  @override
  Future get editDataFuture =>
      HttpCpfContributionService.getCpfContributionID(rolePermission.id);

  @override
  TextEditingController get numberCtl => null;

  @override
  FutureOr<List<PermissionEntity>> transformData(
      List<PermissionEntity> d, bool isCache) {
    if (rolePermission == null) {
      rolePermission = RolePermissionEntity();
    }
    rolePermission.allPermissions = d;
    return super.transformData(d, isCache);
  }

  @override
  String get type => null;
}
